package com.vpen.blog.config.security;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;

import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * -@Version 1.0
 * -@Author:Vpen
 * -@Date:2021/7/8 20:29
 * -@Content: 验证是否携带了Token请求
 */
//@Configuration
//@Component

public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {

    @Autowired
    private JwtTokenUtils jwtTokenUtils;// 封装好的工具累
    
    @Autowired
    private UserDetailsService userDetailsService; // 需要验证密码

    // 配置文件里有写token的前缀，前端是拼接token
    @Value("${jwt.tokenHead}")
    private String tokenHead;

    // 前端存在Session中的token的key
    @Value("${jwt.tokenHeader}")
    private String tokenHeader;

    @Override
    protected void doFilterInternal(HttpServletRequest request,
                                    HttpServletResponse response,
                                    FilterChain filterChain) throws ServletException, IOException {
        String authHeader = request.getHeader(tokenHeader);// 获取请求头里的token
        /* *
         * 作者:Vpen
         * 描述:如果token存在，且是以自己定义的tokenHead开头
         * */
        if (authHeader != null && authHeader.startsWith(tokenHead)) {
            String authToken = authHeader.substring(tokenHead.length());//截取token，前端是存的token = tokenHead+token
            String name = jwtTokenUtils.getUserNameFromToken(authToken);//从token中获取用户名
            // token存在，但是未登录
            if (name != null && null==SecurityContextHolder.getContext().getAuthentication()) {
                // 帮他登录
                UserDetails userDetails = userDetailsService.loadUserByUsername(name);
                // 验证token是否还有效
                if (jwtTokenUtils.validateToken(authToken,userDetails)) {
                    // 重新设置用户对象
                    UsernamePasswordAuthenticationToken authenticationToken =
                            new UsernamePasswordAuthenticationToken(userDetails,null,userDetails.getAuthorities());
                    authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                    SecurityContextHolder.getContext().setAuthentication(authenticationToken);
                }
            }
        }
        filterChain.doFilter(request,response);// 放行
    }
}
